package com.appshelves;

import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ScrollView;

import com.appshelves.layout.Cell;
import com.appshelves.layout.Cell.CellContextMenuInfo;
import com.appshelves.layout.ShelfOverlay.IEditListener;
import com.appshelves.layout.ShelvesLayout;
import com.appshelves.layout.ShelvesOverlay;
import com.appshelves.layout.helpers.IAppClickListener;
import com.appshelves.layout.helpers.ScrollCellAligner;
import com.appshelves.model.App;
import com.appshelves.model.Model;
import com.appshelves.model.Model.Event;
import com.appshelves.model.Model.EventListener;
import com.appshelves.model.Shelf;
import com.appshelves.utils.Profiler;
import com.appshelves.utils.Utils;

public class MainActivity extends EventListenerActivity {

    private ScrollView scroll;
    private ShelvesLayout shelves;
    private FrameLayout baseFrame;
    private ShelvesOverlay overlay;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Profiler p = new Profiler(this, "loading....");

        Utils.setContext(this);
        //        Utils.eraseData(); 
        Settings.init();
        Model.removeAllListeners();

        shelves = new ShelvesLayout(this, createBottomBar(), new IAppClickListener() {
            @Override
            public void onAppClick(App app, Cell cell) {
                startActivitySafely(app.getIntent());
                Model.onAppClicked(app);
                ScrollCellAligner.resetPosition(scroll);
            }
        });

        Model.assureLoaded();
        //        Model.log();

        baseFrame = new FrameLayout(this);
        baseFrame.addView(shelves);

        //        scroll = new ScrollView(this);
        scroll = ScrollCellAligner.createVerticalCellScroller(this, shelves);
        scroll.addView(baseFrame);
        scroll.setPadding(Settings.paddingLeft, Settings.paddingTop, Settings.paddingRight, Settings.paddingBottom);

        setContentView(scroll);

        p.e();
    }

    @Override
    protected void onResume() {
        super.onResume();
        Utils.setContext(this);

        if (Model.performChangeIfNeeded()) {
            assureEditModeClosed();
            ScrollCellAligner.resetPosition(scroll);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Model.save();
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_context, menu);
        App app = ((Cell) v).getApp();
        menu.findItem(R.id.menu_uninstall).setEnabled(!app.isSystem());
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        CellContextMenuInfo info = (CellContextMenuInfo) item.getMenuInfo();
        App app = ((Cell) info.targetView).getApp();
        switch (item.getItemId()) {
            case R.id.menu_uninstall:
                uninstallApp(app);
                return true;
            case R.id.menu_app_info:
                showAppInfo(app);
                return true;
            default:
                return super.onContextItemSelected(item);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        if (isEditMode())
            return false;

        menu.findItem(R.id.menu_edit_shelves).setEnabled(Model.getShelvesNumber() != 0);
        menu.findItem(R.id.menu_add_shelf).setEnabled(Model.getOffShelfAppsNumber() != 0); // TODO manage add button visibility.

        return super.onPrepareOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_add_shelf:
                showEditActivity();
                return true;
            case R.id.menu_edit_shelves:
                beginEditMode();
                return true;
            case R.id.menu_manage_apps:
                showManageApps();
                return true;
            case R.id.menu_settings:
                showSettings();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public void onBackPressed() {
        if (isEditMode())
            assureEditModeClosed();
        else
            super.onBackPressed();
    }

    private boolean isEditMode() {
        return overlay != null && overlay.getParent() != null;
    }

    /// create views

    private void assureEditModeClosed() {
        if (!isEditMode())
            return;

        baseFrame.removeView(overlay);
        shelves.showBottomBar(true);
    }

    private void beginEditMode() {
        shelves.showBottomBar(false);

        if (overlay == null)
            overlay = new ShelvesOverlay(this, new IEditListener() {

                @Override
                public void onEdit(Shelf shelf) {
                    editShelf(shelf);

                }

                @Override
                public void onDelete(Shelf shelf) {
                    deleteShelf(shelf);
                }

            });

        baseFrame.addView(overlay);
    }

    private ViewGroup createBottomBar() {
        ViewGroup bottomBar = (ViewGroup) getLayoutInflater().inflate(R.layout.bottom_bar, null);
        View add = bottomBar.findViewById(R.id.button_add);
        add.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                showEditActivity();
            }
        });

        View options = bottomBar.findViewById(R.id.button_options);
        if (ViewConfiguration.get(this).hasPermanentMenuKey())
            bottomBar.removeView(options);
        else
            options.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    openOptionsMenu();
                }
            });

        return bottomBar;
    }

    /// launch

    void editShelf(Shelf shelf) {
        Model.requestChange(shelf);
        showEditActivity();
    }

    private void uninstallApp(App app) {
        Intent intent = new Intent(Intent.ACTION_DELETE);
        intent.setData(Uri.fromParts("package", app.getPackageName(), null));
        startActivitySafely(intent);
    }

    private void showAppInfo(App app) {
        Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.fromParts("package", app.getPackageName(), null));
        startActivitySafely(intent);
    }

    private void showManageApps() {
        Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS);
        startActivitySafely(intent);
    }

    private void showSettings() {
        Intent intent = new Intent();
        intent.setClass(this, SettingsActivity.class);
        startActivity(intent);
    }

    private void showEditActivity() {
        Intent intent = new Intent();
        intent.setClass(this, ShelfEditActivity.class);
        startActivity(intent);
    }

    private boolean startActivitySafely(Intent intent) {
        try {
            startActivity(intent);
            return true;
        } catch (ActivityNotFoundException e) {
            //            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
            //            Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);
        } catch (SecurityException e) {
            //            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
            //            Log.e(TAG, "Launcher does not have the permission to launch " + intent +
            //                    ". Make sure to create a MAIN intent-filter for the corresponding activity " +
            //                    "or use the exported attribute for this activity. "
            //                    + "tag="+ tag + " intent=" + intent, e);
        }
        return false;
    }

    ///

    private void deleteShelf(Shelf shelf) {
        Model.deleteShelf(shelf);
    }

    ///

    @Override
    protected void addEventListeners() {
        addEventListener(Event.THERE_ARENT_SHELVES, new EventListener() {

            @Override
            public void onEvent(Object args) {
                assureEditModeClosed();
            }
        });

        addEventListener(Event.APP_UNINSTALLED, new EventListener() {

            @Override
            public void onEvent(Object args) {
                onAppUninstalled((App) args);
            }
        });

    }

    private void onAppUninstalled(App app) {
        Utils.showAppToast(R.string.toast_app_uninstalled, app);
    }

}